home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Compilers⁄Interps / GCC-2.3.3r12 / Sources-Targets / arm.md < prev    next >
Encoding:
Text File  |  1993-02-05  |  36.1 KB  |  1,318 lines  |  [TEXT/MPS ]

  1. ;;- Machine description Acorn RISC Machine for GNU compiler
  2. ;;  Copyright (C) 1991 Free Software Foundation, Inc.
  3. ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
  4. ;;             and Martin Simmons (@harleqn.co.uk).
  5.  
  6. ;; This file is part of GNU CC.
  7.  
  8. ;; GNU CC is free software; you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 2, or (at your option)
  11. ;; any later version.
  12.  
  13. ;; GNU CC is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;; GNU General Public License for more details.
  17.  
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with GNU CC; see the file COPYING.  If not, write to
  20. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  23.  
  24. ;; Every template must be output by arm_output_asm_insn, since this keeps
  25. ;; track of the offset of labels within the text segment.  This is needed to
  26. ;; to be able to (correctly) output instructions for loading a value from a
  27. ;; function's constant pool, since different instructions are needed when the
  28. ;; constant pool is more than 4095 bytes away from the PC.
  29.  
  30. ;; Addition insns.
  31.  
  32. (define_insn "adddi3"
  33.   [(set (match_operand:DI 0 "di_operand" "=&r")
  34.     (plus:DI (match_operand:DI 1 "di_operand" "%r")
  35.          (match_operand:DI 2 "di_operand" "r")))]
  36.   ""
  37.   "*
  38.   arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands);
  39.   return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));
  40. ")
  41.  
  42. (define_insn "addsi3"
  43.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  44.     (plus:SI (match_operand:SI 1 "register_operand" "r,r")
  45.          (match_operand:SI 2 "general_operand" "r,n")))]
  46.   ""
  47.   "*
  48.   switch (which_alternative)
  49.     {
  50.     case 0:
  51.       return (arm_output_asm_insn (\"add\\t%0, %1, %2\", operands));
  52.     case 1:
  53.       return (output_add_immediate (operands));
  54.     }
  55. ")
  56.  
  57. (define_insn "addsf3"
  58.   [(set (match_operand:SF 0 "register_operand" "=f")
  59.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  60.          (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  61.   ""
  62.   "*
  63.   return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands));
  64. ")
  65.  
  66. (define_insn "adddf3"
  67.   [(set (match_operand:DF 0 "register_operand" "=f")
  68.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  69.          (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  70.   ""
  71.   "*
  72.   return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
  73. ")
  74.  
  75. (define_insn "subdi3"
  76.   [(set (match_operand:DI 0 "di_operand" "=&r")
  77.     (minus:DI (match_operand:DI 1 "di_operand" "%r")
  78.           (match_operand:DI 2 "di_operand" "r")))]
  79.   ""
  80.   "*
  81.   arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  82.   return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));
  83. ")
  84.  
  85. (define_insn "subsi3"
  86.   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
  87.     (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
  88.           (match_operand:SI 2 "general_operand" "r,n,r")))]
  89.   ""
  90.   "*
  91.   switch (which_alternative)
  92.     {
  93.     case 0:
  94.       return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands));
  95.     case 1:
  96.       operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
  97.       return (output_add_immediate (operands));
  98.     case 2:
  99.       return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands));
  100.     }
  101. ")
  102.  
  103. (define_insn "subsf3"
  104.   [(set (match_operand:SF 0 "register_operand" "=f,f")
  105.     (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  106.           (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
  107.   ""
  108.   "*
  109.   switch (which_alternative)
  110.     {
  111.     case 0:
  112.       return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands));
  113.     case 1:
  114.       return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands));
  115.     }
  116. ")
  117.  
  118. (define_insn "subdf3"
  119.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  120.     (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  121.       (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
  122.   ""
  123.   "*
  124.   switch (which_alternative)
  125.     {
  126.     case 0:
  127.       return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
  128.     case 2:
  129.       return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
  130.     }
  131. ")
  132.  
  133. ;; Multiplication insns
  134.  
  135. ;; The `&' is too strict, but at least generates correct code.
  136. (define_insn "mulsi3"
  137.   [(set (match_operand:SI 0 "register_operand" "=&r")
  138.     (mult:SI (match_operand:SI 1 "register_operand" "%r")
  139.          (match_operand:SI 2 "register_operand" "r")))]
  140.   ""
  141.   "*
  142.   if (REGNO (operands[0]) == REGNO (operands[1]))
  143.     return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands));
  144.   else
  145.     return (arm_output_asm_insn (\"mul\\t%0, %1, %2\", operands));
  146. ")
  147.  
  148. ;; Unnamed templates to match MLA instruction.
  149.  
  150. (define_insn ""
  151.   [(set (match_operand:SI 0 "register_operand" "=&r")
  152.     (plus:SI
  153.       (mult:SI (match_operand:SI 1 "register_operand" "%r")
  154.            (match_operand:SI 2 "register_operand" "r"))
  155.       (match_operand:SI 3 "register_operand" "r")))]
  156.   ""
  157.   "*
  158.   if (REGNO (operands[0]) == REGNO (operands[1]))
  159.     return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
  160.   else
  161.     return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
  162. ")
  163.  
  164. (define_insn ""
  165.   [(set (match_operand:SI 0 "register_operand" "=&r")
  166.     (plus:SI
  167.       (match_operand:SI 3 "register_operand" "r")
  168.       (mult:SI (match_operand:SI 1 "register_operand" "%r")
  169.            (match_operand:SI 2 "register_operand" "r"))))]
  170.   ""
  171.   "*
  172.   if (REGNO (operands[0]) == REGNO (operands[1]))
  173.     return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
  174.   else
  175.     return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
  176. ")
  177.  
  178. (define_insn "mulsf3"
  179.   [(set (match_operand:SF 0 "register_operand" "=f")
  180.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  181.          (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  182.   ""
  183.   "*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));")
  184.  
  185. (define_insn "muldf3"
  186.   [(set (match_operand:DF 0 "register_operand" "=f")
  187.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  188.          (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  189.   ""
  190.   "*
  191.   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
  192. ")
  193.  
  194. ;; Division insns
  195.  
  196. (define_insn "divsf3"
  197.   [(set (match_operand:SF 0 "register_operand" "=f,f")
  198.     (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  199.         (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
  200.   ""
  201.   "*
  202.   switch (which_alternative)
  203.     {
  204.     case 0:
  205.       return (arm_output_asm_insn (\"dvfs\\t%0, %1, %2\", operands));
  206.     case 1:
  207.       return (arm_output_asm_insn (\"rdfs\\t%0, %2, %1\", operands));
  208.     }
  209. ")
  210.  
  211. (define_insn "divdf3"
  212.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  213.     (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  214.         (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
  215.   ""
  216.   "*
  217.   switch (which_alternative)
  218.     {
  219.     case 0:
  220.       return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
  221.     case 1:
  222.       return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
  223.     }
  224. ")
  225.  
  226. ;; Modulo insns
  227.  
  228. (define_insn "modsf3"
  229.   [(set (match_operand:SF 0 "register_operand" "=f")
  230.     (mod:SF (match_operand:SF 1 "register_operand" "f")
  231.         (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  232.   ""
  233.   "*
  234.   return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
  235. ")
  236.  
  237. (define_insn "moddf3"
  238.   [(set (match_operand:DF 0 "register_operand" "=f")
  239.     (mod:DF (match_operand:DF 1 "register_operand" "f")
  240.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  241.   ""
  242.   "*
  243.   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
  244. ")
  245.  
  246. ;; Boolean and,ior,xor insns
  247.  
  248. (define_insn "anddi3"
  249.   [(set (match_operand:DI 0 "di_operand" "=&r")
  250.     (and:DI (match_operand:DI 1 "di_operand" "%r")
  251.         (match_operand:DI 2 "di_operand" "r")))]
  252.   ""
  253.   "*
  254.   arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
  255.   return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));
  256. ")
  257.  
  258. (define_insn "andsi3"
  259.   [(set (match_operand:SI 0 "register_operand" "=r")
  260.     (and:SI (match_operand:SI 1 "register_operand" "r")
  261.         (match_operand:SI 2 "arm_rhs_operand" "rI")))]
  262.   ""
  263.   "*
  264.   return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands));
  265. ")
  266.  
  267. (define_insn "andcbsi3"
  268.   [(set (match_operand:SI 0 "register_operand" "=r")
  269.     (and:SI (match_operand:SI 1 "register_operand" "r")
  270.         (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
  271.   ""
  272.   "*
  273.   return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
  274. ")
  275.  
  276. (define_insn "iordi3"
  277.   [(set (match_operand:DI 0 "di_operand" "=&r")
  278.     (ior:DI (match_operand:DI 1 "di_operand" "%r")
  279.         (match_operand:DI 2 "di_operand" "r")))]
  280.   ""
  281.   "*
  282.   arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
  283.   return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands));
  284. ")
  285.  
  286. (define_insn "iorsi3"
  287.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  288.     (ior:SI (match_operand:SI 1 "register_operand" "r,r")
  289.         (match_operand:SI 2 "nonmemory_operand" "r,n")))]
  290.   ""
  291.   "*
  292.   switch (which_alternative)
  293.     {
  294.     case 0:
  295.       return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands));
  296.     case 1:
  297.       return (output_multi_immediate (operands,
  298.                       \"orr\\t%0, %1, %2\", \"orr\\t%0, %0, %2\",
  299.                          2, INTVAL (operands[2])));
  300.     }
  301. ")
  302.  
  303. (define_insn "xorsi3"
  304.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  305.     (xor:SI (match_operand:SI 1 "register_operand" "r,r")
  306.         (match_operand:SI 2 "nonmemory_operand" "r,n")))]
  307.   ""
  308.   "*
  309.   switch (which_alternative)
  310.     {
  311.     case 0:
  312.       return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands));
  313.     case 1:
  314.       return (output_multi_immediate (operands,
  315.                       \"eor\\t%0, %1, %2\", \"eor\\t%0, %0, %2\",
  316.                       2, INTVAL (operands[2])));
  317.     }
  318. ")
  319.  
  320. ;; Shift and rotation insns
  321.  
  322. (define_insn "ashlsi3"
  323.   [(set (match_operand:SI 0 "register_operand" "=r")
  324.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  325.            (match_operand:SI 2 "general_operand" "rn")))]
  326.   ""
  327.   "*
  328.   return (output_shifted_move (ASHIFT, operands));
  329. ")
  330.  
  331. (define_insn "ashrsi3"
  332.   [(set (match_operand:SI 0 "register_operand" "=r")
  333.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  334.              (match_operand:SI 2 "general_operand" "rn")))]
  335.   ""
  336.   "*
  337.   return (output_shifted_move (ASHIFTRT, operands));
  338. ")
  339.  
  340. ;; lshlsi3 is not defined because shift counts cannot be negative
  341. ;; An unnamed pattern is needed for expansion of zero_extend.
  342.  
  343. (define_insn ""
  344.   [(set (match_operand:SI 0 "register_operand" "=r")
  345.     (lshift:SI (match_operand:SI 1 "register_operand" "r")
  346.            (match_operand:SI 2 "general_operand" "rn")))]
  347.   ""
  348.   "*
  349.   return (output_shifted_move (LSHIFT, operands));
  350. ")
  351.  
  352. (define_insn "lshrsi3"
  353.   [(set (match_operand:SI 0 "register_operand" "=r")
  354.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  355.              (match_operand:SI 2 "general_operand" "rn")))]
  356.   ""
  357.   "*
  358.   return (output_shifted_move (LSHIFTRT, operands));
  359. ")
  360.  
  361. ;; rotlsi3 is not defined yet to see what happens
  362.  
  363. (define_insn "rotrsi3"
  364.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  365.     (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
  366.              (match_operand:SI 2 "general_operand" "r,n")))]
  367.   ""
  368.   "*
  369.   switch (which_alternative)
  370.     {
  371.     case 0:
  372.       return (arm_output_asm_insn (\"mov\\t%0, %1,ror %2\", operands));
  373.     case 1:
  374.       if (INTVAL(operands[2]) > 31)
  375.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
  376.       return (arm_output_asm_insn (\"mov\\t%0, %1,ror%2\", operands));
  377.     }
  378. ")
  379.  
  380. ;; Unary arithmetic insns
  381.  
  382. (define_insn "negdi2"
  383.   [(set (match_operand:DI 0 "di_operand" "=&r")
  384.     (neg:DI (match_operand:DI 1 "di_operand" "r")))]
  385.   ""
  386.   "*
  387.   arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands);
  388.   return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
  389. ")
  390.  
  391. (define_insn "negsi2"
  392.   [(set (match_operand:SI 0 "register_operand" "=r")
  393.     (neg:SI (match_operand:SI 1 "register_operand" "r")))]
  394.   ""
  395.   "*
  396.   return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));
  397. ")
  398.  
  399. (define_insn "negsf2"
  400.   [(set (match_operand:SF 0 "register_operand" "=f")
  401.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  402.   ""
  403.   "*
  404.   return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));
  405. ")
  406.  
  407. (define_insn "negdf2"
  408.   [(set (match_operand:DF 0 "register_operand" "=f")
  409.     (neg:DF (match_operand:DF 1 "register_operand" "f")))]
  410.   ""
  411.   "*
  412.   return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
  413. ")
  414.  
  415. (define_insn "abssf2"
  416.   [(set (match_operand:SF 0 "register_operand" "=f")
  417.      (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  418.   ""
  419.   "*
  420.   return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));
  421. ")
  422.  
  423. (define_insn "absdf2"
  424.   [(set (match_operand:DF 0 "register_operand" "=f")
  425.     (abs:DF (match_operand:DF 1 "register_operand" "f")))]
  426.   ""
  427.   "*
  428.   return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
  429. ")
  430.  
  431. (define_insn "sqrtsf2"
  432.   [(set (match_operand:SF 0 "register_operand" "=f")
  433.     (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
  434.   ""
  435.   "*
  436.   return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));
  437. ")
  438.  
  439. (define_insn "sqrtdf2"
  440.   [(set (match_operand:DF 0 "register_operand" "=f")
  441.     (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
  442.   ""
  443.   "*
  444.   return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
  445. ")
  446.  
  447. (define_insn "one_cmplsi2"
  448.   [(set (match_operand:SI 0 "register_operand" "=r")
  449.     (not:SI (match_operand:SI 1 "register_operand" "r")))]
  450.   ""
  451.   "*
  452.   return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands));
  453. ")
  454.  
  455. ;; Fixed <--> Floating conversion insns
  456.  
  457. (define_insn "floatsisf2"
  458.   [(set (match_operand:SF 0 "register_operand" "=f")
  459.     (float:SF (match_operand:SI 1 "register_operand" "r")))]
  460.   ""
  461.   "*
  462.   return (arm_output_asm_insn (\"flts\\t%0, %1\", operands));
  463. ")
  464.  
  465. (define_insn "floatsidf2"
  466.   [(set (match_operand:DF 0 "register_operand" "=f")
  467.     (float:DF (match_operand:SI 1 "register_operand" "r")))]
  468.   ""
  469.   "*
  470.   return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
  471. ")
  472.  
  473. ;; Truncation insns
  474.  
  475. (define_insn "truncdfsf2"
  476.   [(set (match_operand:SF 0 "register_operand" "=f")
  477.     (float_truncate:SF
  478.      (match_operand:DF 1 "register_operand" "f")))]
  479.   ""
  480.   "*
  481.   return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
  482. ")
  483.  
  484. ;; Zero extension instructions.
  485.  
  486. (define_expand "zero_extendhisi2"
  487.   [(set (match_dup 2)
  488.     (ashift:SI (match_operand:HI 1 "register_operand" "")
  489.            (const_int 16)))
  490.    (set (match_operand:SI 0 "register_operand" "")
  491.     (lshiftrt:SI (match_dup 2)
  492.              (const_int 16)))]
  493.   ""
  494.   "
  495. { operands[1] = gen_lowpart (SImode, operands[1]);
  496.   operands[2] = gen_reg_rtx (SImode); }")
  497.  
  498. (define_insn "zero_extendqihi2"
  499.   [(set (match_operand:HI 0 "register_operand" "=r")
  500.     (zero_extend:HI
  501.      (match_operand:QI 1 "register_operand" "r")))]
  502.   ""
  503.   "*
  504.   return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands));
  505. ")
  506.  
  507. (define_insn "zero_extendqisi2"
  508.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  509.     (zero_extend:SI
  510.      (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  511.   ""
  512.   "*
  513.   switch (which_alternative)
  514.     {
  515.     case 0:
  516.       return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands));
  517.     case 1:
  518.       return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands));
  519.     }
  520. ")
  521.  
  522. (define_expand "extendhisi2"
  523.   [(set (match_dup 2)
  524.     (ashift:SI (match_operand:HI 1 "register_operand" "")
  525.            (const_int 16)))
  526.    (set (match_operand:SI 0 "register_operand" "")
  527.     (ashiftrt:SI (match_dup 2)
  528.              (const_int 16)))]
  529.   ""
  530.   "
  531. { operands[1] = gen_lowpart (SImode, operands[1]);
  532.   operands[2] = gen_reg_rtx (SImode); }")
  533.  
  534. (define_expand "extendqihi2"
  535.   [(set (match_dup 2)
  536.     (ashift:SI (match_operand:QI 1 "register_operand" "")
  537.            (const_int 24)))
  538.    (set (match_operand:HI 0 "register_operand" "")
  539.     (ashiftrt:SI (match_dup 2)
  540.              (const_int 24)))]
  541.   ""
  542.   "
  543. { operands[0] = gen_lowpart (SImode, operands[0]);
  544.   operands[1] = gen_lowpart (SImode, operands[1]);
  545.   operands[2] = gen_reg_rtx (SImode); }")
  546.  
  547. (define_expand "extendqisi2"
  548.   [(set (match_dup 2)
  549.     (ashift:SI (match_operand:QI 1 "register_operand" "")
  550.            (const_int 24)))
  551.    (set (match_operand:SI 0 "register_operand" "")
  552.     (ashiftrt:SI (match_dup 2)
  553.              (const_int 24)))]
  554.   ""
  555.   "
  556. { operands[1] = gen_lowpart (SImode, operands[1]);
  557.   operands[2] = gen_reg_rtx (SImode); }")
  558.  
  559. (define_insn "extendsfdf2"
  560.   [(set (match_operand:DF 0 "register_operand" "=f")
  561.     (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
  562.   ""
  563.   "*
  564.   return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
  565. ")
  566.  
  567. ;; Move insns (including loads and stores)
  568.  
  569. ;; XXX Just some ideas about movti.
  570.  
  571. ;;(define_expand "loadti"
  572. ;;  [(set (match_operand:TI 0 "register_operand" "")
  573. ;;    (mem:TI (match_operand:SI 1 "address_operand" "")))]
  574. ;;  "" "")
  575.  
  576. ;;(define_expand "storeti"
  577. ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
  578. ;;    (match_operand:TI 1 "register_operand" ""))]
  579. ;;  "" "")
  580.  
  581. ;;(define_expand "movti"
  582. ;;  [(set (match_operand:TI 0 "general_operand" "")
  583. ;;    (match_operand:TI 1 "general_operand" ""))]
  584. ;;  ""
  585. ;;  "
  586. ;;{
  587. ;;  rtx insn;
  588. ;;
  589. ;;  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  590. ;;    operands[1] = copy_to_reg (operands[1]);
  591. ;;  if (GET_CODE (operands[0]) == MEM)
  592. ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
  593. ;;  else if (GET_CODE (operands[1]) == MEM)
  594. ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
  595. ;;  else
  596. ;;    FAIL;
  597. ;;
  598. ;;  emit_insn (insn);
  599. ;;  DONE;
  600. ;;}")
  601.  
  602. ;; Recognise garbage generated above.
  603.  
  604. ;;(define_insn ""
  605. ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
  606. ;;    (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
  607. ;;  ""
  608. ;;  "*
  609. ;;  {
  610. ;;    register mem = (which_alternative < 3);
  611. ;;    register char *template;
  612. ;;
  613. ;;    operands[mem] = XEXP (operands[mem], 0);
  614. ;;    switch (which_alternative)
  615. ;;      {
  616. ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
  617. ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
  618. ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
  619. ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
  620. ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
  621. ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
  622. ;;      }
  623. ;;    return (arm_output_asm_insn (template, operands));
  624. ;;  }")
  625.  
  626.  
  627. (define_insn "movdi"
  628.   [(set (match_operand:DI 0 "di_operand" "=r,r,r,o,r")
  629.     (match_operand:DI 1 "di_operand" "r,n,o,r,F"))]
  630.   ""
  631.   "*
  632.   return (output_move_double (operands));
  633. ")
  634.  
  635. (define_insn "movsi"
  636.   [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
  637.     (match_operand:SI 1 "general_operand"  "r,n,m,r"))]
  638.   ""
  639.   "*
  640.   switch (which_alternative)
  641.     {
  642.     case 0:
  643.       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
  644.     case 1:
  645.       return (output_mov_immediate (operands));
  646.     case 2:
  647.       if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
  648.       &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
  649.     return (arm_output_llc (operands));
  650.       else
  651.     return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
  652.     case 3:
  653.       return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
  654.     }
  655. ")
  656.  
  657. ;; XXX The movhi stuff isn't as correct or as nice as it could be...
  658.  
  659. ;; Subroutine to load a half word into a register from memory.
  660. ;; Operand 0 is the destination register (HImode).
  661. ;; Operand 1 is the source address (SImode).
  662. ;; Operand 2 is a temporary (SImode).
  663.  
  664. ;;(define_expand "loadhi"
  665. ;;  [;; load the whole word (ARM realigns it if not on word boundary)
  666. ;;   (set (match_operand:SI 2 "register_operand" "")
  667. ;;        (mem:SI (match_operand:SI 1 "address_operand" "")))
  668. ;;   ;; quietly forget the upper 16 bits
  669. ;;   (set (match_operand:HI 0 "register_operand" "")
  670. ;;        (subreg:HI (match_dup 2) 0))]
  671. ;;  ""
  672. ;;  ""
  673. ;;)
  674.  
  675. ;; Load op0 from mem:op1.  Subroutine in case we're reloading and the normal
  676. ;; loadhi is not allowed.
  677.  
  678. ;;(define_expand "reloadhi"
  679. ;;  [(set (reg:SI 10)
  680. ;;    (mem:SI (match_operand:SI 1 "address_operand" "")))
  681. ;;   (set (match_operand:HI 0 "register_operand" "")
  682. ;;    (subreg:HI (reg:SI 10) 0))]
  683. ;;  "" "")
  684.  
  685. ;; Store op0 into mem:op1.  Subroutine in case we're reloading and the normal
  686. ;; storehi is not allowed.
  687.  
  688. (define_expand "restorehi"
  689.   [(set (mem:QI (match_operand 1 "" ""))
  690.     (match_dup 2))
  691.    (set (reg:SI 10)
  692.     (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
  693.    (set (mem:QI (plus:SI (match_dup 1) (const_int 1)))
  694.     (reg:QI 10))]
  695.   ""
  696.   "
  697. {
  698.   operands[2] = gen_lowpart (QImode, operands[0]);
  699.   operands[0] = gen_lowpart (SImode, operands[0]);
  700. }")
  701.  
  702. ;; Subroutine to store a half word from a register into memory.
  703. ;; Operand 0 is the source register (HImode)
  704. ;; Operand 1 is the destination address in a register (SImode)
  705.  
  706. (define_expand "storehi"
  707.   [;; store the low byte
  708.    (set (mem:QI (match_operand 1 "" "")) (match_dup 3))
  709.    ;; extract the high byte
  710.    (set (match_dup 2)
  711.     (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
  712.    ;; store the high byte
  713.    (set (mem:QI (plus (match_dup 1) (const_int 1)))
  714.     (subreg:QI (match_dup 2) 0))]    ;explicit subreg safe
  715.   ""
  716.   "
  717. { operands[3] = gen_lowpart (QImode, operands[0]);
  718.   operands[0] = gen_lowpart (SImode, operands[0]);
  719.   operands[2] = gen_reg_rtx (SImode); }")
  720.  
  721. ;; Subroutine to store a half word integer constant into memory.
  722. ;; Operand 0 is the constant
  723. ;; Operand 1 is the destination address in a register (SImode)
  724.  
  725. (define_expand "storeinthi"
  726.   [;; store the low byte
  727.    (set (mem:QI (match_operand 1 "" "")) (match_operand 0 "" ""))
  728.    ;; store the high byte
  729.    (set (mem:QI (plus (match_dup 1) (const_int 1)))
  730.     (match_dup 2))]
  731.   ""
  732.   "
  733.     {
  734.       int value = INTVAL (operands[0]);
  735.  
  736.       operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
  737.       operands[2] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
  738.     }
  739. ")
  740.  
  741. (define_expand "movhi"
  742.   [(set (match_operand:HI 0 "general_operand" "")
  743.     (match_operand:HI 1 "general_operand" ""))]
  744.   ""
  745.   "
  746. {
  747.   rtx insn;
  748.  
  749.   if (reload_in_progress || reload_completed)
  750.     {
  751.       if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == REG)
  752.     insn = gen_restorehi (operands[1], XEXP (operands[0], 0));
  753.       else
  754.     insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
  755.     }
  756.   else
  757.     {
  758.       if (GET_CODE (operands[0]) == MEM)
  759.     {
  760.       if (GET_CODE (operands[1]) == CONST_INT)
  761.         {
  762.           insn = gen_storeinthi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
  763.         }
  764.       else
  765.         {
  766.           if (GET_CODE (operands[1]) == MEM)
  767.         operands[1] = copy_to_reg (operands[1]);
  768.           insn = gen_storehi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
  769.         }
  770.     }
  771. #if 0
  772.       else if (GET_CODE (operands[1]) == MEM)
  773.     {
  774.       insn = gen_loadhi (operands[0], XEXP (operands[1], 0),
  775.                  gen_reg_rtx (SImode));
  776.     }
  777. #endif
  778.       else
  779.     insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
  780.     }
  781.  
  782.   emit_insn (insn);
  783.   DONE;
  784. }")
  785.  
  786. ;; Pattern to recognise insn generated default case above
  787.  
  788. (define_insn ""
  789.   [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
  790.     (match_operand:HI 1 "general_operand"  "r,n,m,r"))]
  791.   ""
  792.   "*
  793.   switch (which_alternative)
  794.     {
  795.       case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands));
  796.       case 1: return (output_mov_immediate (operands));
  797.       case 2: return (arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands));
  798.       case 3: return (arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands));
  799.     }
  800. ")
  801.  
  802. (define_insn "movqi"
  803.   [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
  804.     (match_operand:QI 1 "general_operand" "r,n,m,r"))]
  805.   ""
  806.   "*
  807.   switch (which_alternative)
  808.     {
  809.     case 0:
  810.       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
  811.     case 1:
  812.       return (output_mov_immediate (operands));
  813.     case 2:
  814.       return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands));
  815.     case 3:
  816.       return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
  817.     }
  818. ")
  819.  
  820. (define_insn "movsf"
  821.   [(set (match_operand:SF 0 "general_operand" "=f,f,m,f,r,r")
  822.     (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))]
  823.   ""
  824.   "*
  825.   switch (which_alternative)
  826.     {
  827.     case 0:
  828.       return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
  829.     case 1:
  830.       return (arm_output_asm_insn (\"ldfs\\t%0, %1\", operands));
  831.     case 2:
  832.       return (arm_output_asm_insn (\"stfs\\t%1, %0\", operands));
  833.     case 3:
  834.       arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands);
  835.       return (arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands));
  836.     case 4:
  837.       arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands);
  838.       return (arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands));
  839.     case 5:
  840.       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
  841.   }
  842. ")
  843.  
  844. (define_insn "movdf"
  845.   [(set (match_operand:DF 0 "general_operand" "=f,f,m,f,r,r")
  846.     (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))]
  847.   ""
  848.   "*
  849.   switch (which_alternative)
  850.     {
  851.       case 0: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
  852.       case 1: return (arm_output_asm_insn (\"ldfd\\t%0, %1\", operands));
  853.       case 2: return (arm_output_asm_insn (\"stfd\\t%1, %0\", operands));
  854.       case 3: return (output_mov_double_fpu_from_arm (operands));
  855.       case 4: return (output_mov_double_arm_from_fpu (operands));
  856.       case 5: return (output_move_double (operands));
  857.     }
  858. ")
  859.  
  860. ;; Comparison and test insns
  861.  
  862. (define_insn "cmpsi"
  863.   [(set (cc0)
  864.     (compare (match_operand:SI 0 "register_operand" "r")
  865.          (match_operand:SI 1 "arm_rhs_operand" "rI")))]
  866.   ""
  867.   "*
  868.   return (arm_output_asm_insn (\"cmp\\t%0, %1\", operands));
  869. ")
  870.  
  871. (define_insn "tstsi"
  872.   [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
  873.   ""
  874.   "*
  875.   return (arm_output_asm_insn (\"cmp\\t%0, #0\", operands));
  876. ")
  877.  
  878. (define_insn ""
  879.   [(set (cc0)
  880.     (compare (match_operand:SI 0 "register_operand" "r")
  881.          (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))]
  882.   ""
  883.   "*
  884.   return (arm_output_asm_insn (\"cmn\\t%0, %1\", operands));
  885. ")
  886.  
  887. (define_insn "cmpsf"
  888.   [(set (cc0)
  889.     (compare (match_operand:SF 0 "register_operand" "f")
  890.          (match_operand:SF 1 "fpu_rhs_operand" "fG")))]
  891.   ""
  892.   "*
  893.   return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
  894. ")
  895.  
  896. (define_insn "cmpdf"
  897.   [(set (cc0)
  898.     (compare (match_operand:DF 0 "register_operand" "f")
  899.          (match_operand:DF 1 "fpu_rhs_operand" "fG")))]
  900.   ""
  901.   "*
  902.   return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
  903. ")
  904.  
  905. ;; Conditional branch insns
  906.  
  907. (define_insn "beq"
  908.   [(set (pc)
  909.     (if_then_else (eq (cc0) (const_int 0))
  910.               (label_ref (match_operand 0 "" ""))
  911.               (pc)))]
  912.   ""
  913.   "*
  914.   return (arm_output_asm_insn (\"beq\\t%l0\", operands));
  915. ")
  916.  
  917. (define_insn "bne"
  918.   [(set (pc)
  919.     (if_then_else (ne (cc0) (const_int 0))
  920.               (label_ref (match_operand 0 "" ""))
  921.               (pc)))]
  922.   ""
  923.   "*
  924.   return (arm_output_asm_insn (\"bne\\t%l0\", operands));
  925. ")
  926.  
  927. (define_insn "bgt"
  928.   [(set (pc)
  929.     (if_then_else (gt (cc0) (const_int 0))
  930.               (label_ref (match_operand 0 "" ""))
  931.               (pc)))]
  932.   ""
  933.   "*
  934.   return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
  935. ")
  936.  
  937. (define_insn "ble"
  938.   [(set (pc)
  939.     (if_then_else (le (cc0) (const_int 0))
  940.               (label_ref (match_operand 0 "" ""))
  941.               (pc)))]
  942.   ""
  943.   "*
  944.   return (arm_output_asm_insn (\"ble\\t%l0\", operands));
  945. ")
  946.  
  947. (define_insn "bge"
  948.   [(set (pc)
  949.     (if_then_else (ge (cc0) (const_int 0))
  950.               (label_ref (match_operand 0 "" ""))
  951.               (pc)))]
  952.   ""
  953.   "*
  954.   return (arm_output_asm_insn (\"bge\\t%l0\", operands));
  955. ")
  956.  
  957. (define_insn "blt"
  958.   [(set (pc)
  959.     (if_then_else (lt (cc0) (const_int 0))
  960.               (label_ref (match_operand 0 "" ""))
  961.               (pc)))]
  962.   ""
  963.   "*
  964.   return (arm_output_asm_insn (\"blt\\t%l0\", operands));
  965. ")
  966.  
  967. (define_insn "bgtu"
  968.   [(set (pc)
  969.     (if_then_else (gtu (cc0) (const_int 0))
  970.               (label_ref (match_operand 0 "" ""))
  971.               (pc)))]
  972.   ""
  973.   "*
  974.   return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
  975. ")
  976.  
  977. (define_insn "bleu"
  978.   [(set (pc)
  979.     (if_then_else (leu (cc0) (const_int 0))
  980.               (label_ref (match_operand 0 "" ""))
  981.               (pc)))]
  982.   ""
  983.   "*
  984.   return (arm_output_asm_insn (\"bls\\t%l0\", operands));
  985. ")
  986.  
  987. (define_insn "bgeu"
  988.   [(set (pc)
  989.     (if_then_else (geu (cc0) (const_int 0))
  990.               (label_ref (match_operand 0 "" ""))
  991.               (pc)))]
  992.   ""
  993.   "*
  994.   return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
  995. ")
  996.  
  997. (define_insn "bltu"
  998.   [(set (pc)
  999.     (if_then_else (ltu (cc0) (const_int 0))
  1000.               (label_ref (match_operand 0 "" ""))
  1001.               (pc)))]
  1002.   ""
  1003.   "*
  1004.   return (arm_output_asm_insn (\"blo\\t%l0\", operands));
  1005. ")
  1006.  
  1007. ;; Inverted conditional branch insns
  1008.  
  1009. (define_insn ""
  1010.   [(set (pc)
  1011.     (if_then_else (eq (cc0) (const_int 0))
  1012.               (pc)
  1013.               (label_ref (match_operand 0 "" ""))))]
  1014.   ""
  1015.   "*
  1016.   return (arm_output_asm_insn (\"bne\\t%l0\", operands));
  1017. ")
  1018.  
  1019. (define_insn ""
  1020.   [(set (pc)
  1021.     (if_then_else (ne (cc0) (const_int 0))
  1022.               (pc)
  1023.               (label_ref (match_operand 0 "" ""))))]
  1024.   ""
  1025.   "*
  1026.   return (arm_output_asm_insn (\"beq\\t%l0\", operands));
  1027. ")
  1028.  
  1029. (define_insn ""
  1030.   [(set (pc)
  1031.     (if_then_else (gt (cc0) (const_int 0))
  1032.               (pc)
  1033.               (label_ref (match_operand 0 "" ""))))]
  1034.   ""
  1035.   "*
  1036.   return (arm_output_asm_insn (\"ble\\t%l0\", operands));
  1037. ")
  1038.  
  1039. (define_insn ""
  1040.   [(set (pc)
  1041.     (if_then_else (le (cc0) (const_int 0))
  1042.               (pc)
  1043.               (label_ref (match_operand 0 "" ""))))]
  1044.   ""
  1045.   "*
  1046.   return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
  1047. ")
  1048.  
  1049. (define_insn ""
  1050.   [(set (pc)
  1051.     (if_then_else (ge (cc0) (const_int 0))
  1052.               (pc)
  1053.               (label_ref (match_operand 0 "" ""))))]
  1054.   ""
  1055.   "*
  1056.   return (arm_output_asm_insn (\"blt\\t%l0\", operands));
  1057. ")
  1058.  
  1059. (define_insn ""
  1060.   [(set (pc)
  1061.     (if_then_else (lt (cc0) (const_int 0))
  1062.               (pc)
  1063.               (label_ref (match_operand 0 "" ""))))]
  1064.   ""
  1065.   "*
  1066.   return (arm_output_asm_insn (\"bge\\t%l0\", operands));
  1067. ")
  1068.  
  1069. (define_insn ""
  1070.   [(set (pc)
  1071.     (if_then_else (gtu (cc0) (const_int 0))
  1072.               (pc)
  1073.               (label_ref (match_operand 0 "" ""))))]
  1074.   ""
  1075.   "*
  1076.   return (arm_output_asm_insn (\"bls\\t%l0\", operands));
  1077. ")
  1078.  
  1079. (define_insn ""
  1080.   [(set (pc)
  1081.     (if_then_else (leu (cc0) (const_int 0))
  1082.               (pc)
  1083.               (label_ref (match_operand 0 "" ""))))]
  1084.   ""
  1085.   "*
  1086.   return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
  1087. ")
  1088.  
  1089. (define_insn ""
  1090.   [(set (pc)
  1091.     (if_then_else (geu (cc0) (const_int 0))
  1092.               (pc)
  1093.               (label_ref (match_operand 0 "" ""))))]
  1094.   ""
  1095.   "*
  1096.   return (arm_output_asm_insn (\"blo\\t%l0\", operands));
  1097. ")
  1098.  
  1099. (define_insn ""
  1100.   [(set (pc)
  1101.     (if_then_else (ltu (cc0) (const_int 0))
  1102.               (pc)
  1103.               (label_ref (match_operand 0 "" ""))))]
  1104.   ""
  1105.   "*
  1106.   return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
  1107. ")
  1108.  
  1109. ;; Jump and linkage insns
  1110. ;; `return' is still a jump-to-epilogue...
  1111.  
  1112. (define_insn "jump"
  1113.   [(set (pc)
  1114.     (label_ref (match_operand 0 "" "")))]
  1115.   ""
  1116.   "*
  1117.   return (arm_output_asm_insn (\"b\\t%l0\", operands));
  1118. ")
  1119.  
  1120. (define_insn "call"
  1121.   [(call (match_operand 0 "memory_operand" "m")
  1122.      (match_operand 1 "general_operand" "g"))
  1123.    (clobber (reg:SI 14))]
  1124.   ""
  1125.   "*
  1126.   return (output_call (operands));
  1127. ")
  1128.  
  1129. (define_insn "call_value"
  1130.   [(set (match_operand 0 "" "=rf")
  1131.     (call (match_operand 1 "memory_operand" "m")
  1132.     (match_operand 2 "general_operand" "g")))
  1133.    (clobber (reg:SI 14))]
  1134.   ""
  1135.   "*
  1136.   return (output_call (&operands[1]));
  1137. ")
  1138.  
  1139. ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
  1140. ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
  1141.  
  1142. (define_insn ""
  1143.   [(call (mem:SI (match_operand:SI 0 "" "i"))
  1144.      (match_operand:SI 1 "general_operand" "g"))
  1145.    (clobber (reg:SI 14))]
  1146.   "GET_CODE (operands[0]) == SYMBOL_REF"
  1147.   "*
  1148.   return (arm_output_asm_insn (\"bl\\t%a0\", operands));
  1149. ")
  1150.  
  1151. (define_insn ""
  1152.   [(set (match_operand 0 "register_operand" "=rf")
  1153.     (call (mem:SI (match_operand:SI 1 "" "i"))
  1154.     (match_operand:SI 2 "general_operand" "g")))
  1155.    (clobber (reg:SI 14))]
  1156.   "GET_CODE(operands[1]) == SYMBOL_REF"
  1157.   "*
  1158.   return (arm_output_asm_insn (\"bl\\t%a1\", operands));
  1159. ")
  1160.  
  1161. (define_insn "tablejump"
  1162.   [(set (pc)
  1163.     (match_operand:SI 0 "register_operand" "r"))
  1164.    (use (label_ref (match_operand 1 "" "")))]
  1165.   ""
  1166.   "*
  1167.   return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", operands));
  1168. ")
  1169.  
  1170. (define_insn "indirect_jump"
  1171.   [(set (pc)
  1172.     (match_operand:SI 0 "register_operand" "r"))]
  1173.   ""
  1174.   "*
  1175.   return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands));
  1176. ")
  1177.  
  1178. ;; Misc insns
  1179.  
  1180. (define_insn "nop"
  1181.   [(const_int 0)]
  1182.   ""
  1183.   "*
  1184.   return (arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands));
  1185. ")
  1186.  
  1187. ;; Patterns to allow combination of arithmetic, cond code and shifts
  1188.  
  1189. ;(define_insn ""
  1190. ;  [(set (match_operand:SI 0 "register_operand" "=r")
  1191. ;        (match_operator:SI 1 "shiftable_operator"
  1192. ;          [(match_operand:SI 2 "register_operand" "r")
  1193. ;           (match_operator:SI 3 "shift_operator"
  1194. ;             [(match_operand:SI 4 "register_operand" "r")
  1195. ;          (match_operand:SI 5 "nonmemory_operand" "rn")])]))]
  1196. ;  ""
  1197. ;  "*
  1198. ;  return (output_arithmetic_with_shift (operands, FALSE, FALSE));
  1199. ;  "
  1200. ;)
  1201.  
  1202. ;(define_insn ""
  1203. ;  [(set (match_operand:SI 0 "register_operand" "=r")
  1204. ;        (match_operator:SI 1 "shiftable_operator"
  1205. ;          [(match_operator:SI 3 "shift_operator"
  1206. ;             [(match_operand:SI 4 "register_operand" "r")
  1207. ;              (match_operand:SI 5 "nonmemory_operand" "rI")])
  1208. ;           (match_operand:SI 2 "register_operand" "r")]))]
  1209. ;  ""
  1210. ;  "*
  1211. ;  return (output_arithmetic_with_shift (operands, TRUE, FALSE));
  1212. ;")
  1213.  
  1214. ;; Patterns to allow combination of arithmetic and multiplication
  1215.  
  1216. ;(define_insn ""
  1217. ;  [(set (match_operand:SI 0 "register_operand" "=r")
  1218. ;        (match_operator:SI 1 "shiftable_operator"
  1219. ;          [(match_operand:SI 2 "register_operand" "r")
  1220. ;             (mult:SI
  1221. ;               (match_operand:SI 3 "register_operand" "r")
  1222. ;               (match_operand:SI 4 "power_of_two_operand" "n"))]))]
  1223. ;  ""
  1224. ;  "*
  1225. ;  return (output_arithmetic_with_immediate_multiply (operands, FALSE));
  1226. ;")
  1227.  
  1228. ; Uncomment this to show combiner problem (see ../COMBINER-PROBLEM).
  1229. ;(define_insn ""
  1230. ;  [(set (match_operand:SI 0 "register_operand" "=r")
  1231. ;        (match_operator:SI 1 "shiftable_operator"
  1232. ;      [(mult:SI
  1233. ;        (match_operand:SI 3 "register_operand" "r")
  1234. ;        (match_operand:SI 4 "power_of_two_operand" "n"))
  1235. ;       (match_operand:SI 2 "register_operand" "r")]))]
  1236. ;  ""
  1237. ;  "*
  1238. ;  return (output_arithmetic_with_immediate_multiply (operands, TRUE));
  1239. ;")
  1240.  
  1241. ;; Peephole optimizations.
  1242.  
  1243. ;; When testing a bitset smaller than 9 bits for (un)equality, a
  1244. ;; shift/and/cmp/b{eq,ne} sequence can be replaced by one tst and the same
  1245. ;; branch sequence.
  1246.  
  1247. ;;(define_peephole
  1248. ;;  [(set (match_operand:SI 0 "register_operand" "=r")
  1249. ;;    (lshiftrt:SI (match_dup 0)
  1250. ;;             (match_operand 1 "immediate_operand" "")))
  1251. ;;   (set (match_dup 0)
  1252. ;;    (and:SI (match_dup 0)
  1253. ;;        (match_operand 2 "immediate_operand" "")))
  1254. ;;   (set (cc0) (match_dup 0))
  1255. ;;   (set (pc)
  1256. ;;    (if_then_else (ne (cc0) (const_int 0))
  1257. ;;              (label_ref (match_operand 3 "" ""))
  1258. ;;              (pc)))]
  1259. ;;  "dead_or_set_p (PREV_INSN (insn), operands[0])
  1260. ;;   && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
  1261. ;;   && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
  1262. ;;  "*
  1263. ;;  operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1264. ;;                         INTVAL (operands[2]) << INTVAL (operands[1]));
  1265. ;;  arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
  1266. ;;  return (arm_output_asm_insn (\"bne\\t%l3\", operands));
  1267. ;;")
  1268.  
  1269. ;;(define_peephole
  1270. ;;  [(set (match_operand:SI 0 "register_operand" "=r")
  1271. ;;    (lshiftrt:SI (match_dup 0)
  1272. ;;             (match_operand 1 "immediate_operand" "")))
  1273. ;;   (set (match_dup 0)
  1274. ;;    (and:SI (match_dup 0)
  1275. ;;        (match_operand 2 "immediate_operand" "")))
  1276. ;;   (set (cc0) (match_dup 0))
  1277. ;;   (set (pc)
  1278. ;;    (if_then_else (ne (cc0) (const_int 0))
  1279. ;;              (pc)
  1280. ;;              (label_ref (match_operand 3 "" ""))))]
  1281. ;;  "dead_or_set_p (prev_real_insn (insn), operands[0])
  1282. ;;   && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
  1283. ;;   && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
  1284. ;;  "*
  1285. ;;  operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1286. ;;                         INTVAL (operands[2]) << INTVAL (operands[1]));
  1287. ;;  arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
  1288. ;;  return (arm_output_asm_insn (\"beq\\t%l3\", operands));
  1289. ;;")
  1290.  
  1291. ;; This allows negative constants to be compared since GCC appears not to try
  1292. ;; converting them with a NEG.
  1293.  
  1294. ;;(define_peephole
  1295. ;;  [(set (match_operand:SI 2 "register_operand" "=r")
  1296. ;;        (match_operand:SI 1 "immediate_operand" "n"))
  1297. ;;   (set (cc0)
  1298. ;;        (compare (match_operand:SI 0 "register_operand" "r")
  1299. ;;                 (match_dup 1)))]
  1300. ;;  "const_ok_for_arm (-INTVAL (operands[1]))
  1301. ;;   && dead_or_set_p (prev_real_insn (insn), operands[0])"
  1302. ;;  "*
  1303. ;;  operands[1] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
  1304. ;;  return (arm_output_asm_insn (\"cmn\\t%0, %1\\t\\t@ ph negate comparison\", operands));
  1305. ;;")
  1306.  
  1307. ;; Local variables:
  1308. ;; mode:emacs-lisp
  1309. ;; eval: (setq comment-start ";; ")
  1310. ;; eval: (setq comment-end "")
  1311. ;; eval: (setq comment-start-skip ";;+ *")
  1312. ;; eval: (set-syntax-table (copy-sequence (syntax-table)))
  1313. ;; eval: (modify-syntax-entry ?[ "(]")
  1314. ;; eval: (modify-syntax-entry ?] ")[")
  1315. ;; eval: (modify-syntax-entry ?{ "(}")
  1316. ;; eval: (modify-syntax-entry ?} "){")
  1317. ;; End:
  1318.